package com.yy.job.utils;

import java.io.InputStream;
import java.io.StringWriter;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;

public class JaxbUtils {
	
	public static final String FEATURE1 = "http://apache.org/xml/features/disallow-doctype-decl";
	public static final String FEATURE2 = "http://xml.org/sax/features/external-general-entities";
	public static final String FEATURE3 = "http://xml.org/sax/features/external-parameter-entities";
	public static final String FEATURE4 = "http://apache.org/xml/features/nonvalidating/load-external-dtd";
	
	private static final Logger log = LoggerFactory.getLogger(JaxbUtils.class);

	public static String convertToXml(Object obj, String encoding) {
		String result = null;
		try {
			JAXBContext context = JAXBContext.newInstance(new Class[] { obj.getClass() });
			Marshaller marshaller = context.createMarshaller();
			marshaller.setProperty("jaxb.formatted.output", Boolean.valueOf(true));
			marshaller.setProperty("jaxb.encoding", encoding);
			StringWriter writer = new StringWriter();
			marshaller.marshal(obj, writer);
			result = writer.toString();
		} catch (Exception e) {
			log.error("JaxbUtil convertToXml exception:", e);
		}
		return result;
	}

	public static <T> T converyToJavaBean(InputStream inputStream, Class<T> c) {
		T t = null;
		try {
			// 防止XXE攻击
			// 为避免 XXE 注入，请勿使用将 XML 源直接处理为 java.io.File、java.io.Reader 或java.io.InputStream
			// 使用安全配置的解析器解析文档，并使用将安全解析器作为 XML 源的解组方法
			DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
			dbf.setFeature(FEATURE1, true);
			dbf.setFeature(FEATURE2, false);
			dbf.setFeature(FEATURE3, false);
			dbf.setFeature(FEATURE4, false);
			dbf.setXIncludeAware(false);
			dbf.setExpandEntityReferences(false);
			
			DocumentBuilder db = dbf.newDocumentBuilder();
			Document document = db.parse(inputStream, "UTF-8");
			
			JAXBContext context = JAXBContext.newInstance(new Class[] { c });
			Unmarshaller unmarshaller = context.createUnmarshaller();
			
			t = (T) unmarshaller.unmarshal(document);
		} catch (Exception e) {
			log.error("JaxbUtil convery inputStream ToJavaBean exception:", e);
		}
		return t;
	}
}
